當畫面開始變得複雜,AJAX 請求可能不是簡單的單一元素加上一個請求、一個回應,這時候就可以使用 hx-sync
來處理多個元素之間 AJAX 請求的同步關係。
屬性撰寫方式是hx-sync="CSS選擇器 :同步方式"
,可以使用的同步方式如下:
以下是官方範例情境,在沒設定 hx-sync 時,當 submit 觸發,/validate 和 /store 兩個 AJAX 請求都會被觸發,在 input 標籤上設定了 hx-sync="closest form:abort"
屬性後,如果 form 發出了請求,input 也正在發送請求,則 input 的請求會被中斷。
<form hx-post="/store">
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change"
hx-sync="closest form:abort">
<button type="submit">Submit</button>
</form>
上面的範例是發送表單優先,如果要改成優先驗證表單(input 的請求為主),可以改成使用 drop,當 input 請求中 form 的請求也被觸發,就會放棄 form 的請求。
<form hx-post="/store">
<input id="title" name="title" type="text"
hx-post="/validate"
hx-trigger="change"
hx-sync="closest form:drop"
>
<button type="submit">Submit</button>
</form>
當表單有很多欄位時,可以不用在每個欄位加上 hx-sync,而是放在 form 元素上統一設定同步行為,如果提交表單優先可以設置hx-sync="this:replace"
,反之,欄位驗證優先可以設置hx-sync="this:abort"
。
<form hx-post="/store" hx-sync="this:replace">
<input id="title" name="title" type="text" hx-post="/validate" hx-trigger="change" />
<button type="submit">Submit</button>
</form>
以搜尋為例,可以用 hx-trigger 搭配 delay 實作 debounce 的功能,但是如果請求送出後,input 還是持續輸入改變,收到回應時的當下內容已經不是 input 內的值應該要查到的結果,這種情況可以搭配hx-sync="this:replace"
把先前的請求給取消,替換成最新的請求。
<input type="search"
hx-get="/search"
hx-trigger="keyup changed delay:500ms, search"
hx-target="#search-results"
hx-sync="this:replace">
參考資料:https://htmx.org/attributes/hx-sync/